﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Xna.Framework;
using System.Collections;
using Microsoft.Xna.Framework.Graphics;

namespace FUSE
{



        /// <summary>
        /// NOTE: please use descriptive names instead of gc use galaxyComponent, or gravMap vs gravityMap
        /// The extra characters will help undertand the function instantly
        /// also please do not commit broken code
        /// please create a contract to your function before committing
        /// please declare all your variables at the top of the class or function
        /// </summary>
        public static class PhysicsEngine
        {
            public static int k_looks_good = 100;
            public static int colorMapTransparency = 16; //semi clear
            public static double minXForce = 1;



            /// <summary>
            /// Generates a new gravity map
            /// </summary>
            /// <param name="galaxy"></param>
            /// NOTE: Think about making gravityGrid be type GenericForces[,] this was we can have child SlingForces(for slingOrbit) CrashFroces(for CrashOrbit)
            /// NOTE: Needs to be tested
            /// <returns></returns>
            public static void createGravityGrid2(Map mapToMark)
            {

                //int planetMass;
                //double crashRadius; //not needed here
                //double slingRadius;

                //int centerX;
                //int centerY;

                //double maxY;
                //int maxX;


                int xSize = mapToMark.getXSize();
                int ySize = mapToMark.getYSize();

                mapToMark.absoluteForceMap = new float[xSize, ySize];

                mapToMark.galaxyForces = null;


                //Create gravity grid
                mapToMark.galaxyForces = new GenericForce[xSize, ySize];

                for (int xC = 0; xC < xSize; xC++)
                {
                    for (int yC = 0; yC < ySize; yC++)
                    {
                        mapToMark.galaxyForces[xC, yC] = new GenericForce();
                    }
                }

                //For every object with mass in the galaxy table create a slingshot gravity area
                //also a crash gravity area
                foreach (DictionaryEntry entry in mapToMark.galaxyComponentsTable)
                {
                    //Console.WriteLine("Before GRID Create");
                    Debug.Assert(entry.Key != null);
                    if (entry.Value is MassedComponent)
                    {
                        plotMassedComponent(entry, mapToMark);
                    }
                    else if (entry.Value is Wormhole)
                    {
                        //NO forces for wormhole
                    }
                    

                }
                Console.WriteLine("Physics ENGADGED!!!");
                //return mapToMark.galaxyForces;


            }

            private static void plotMassedComponent(DictionaryEntry entry, Map galaxy)
            {
                double outerRadius;
                double innerRadius;

                GenericForce[,] newGravityMap = galaxy.galaxyForces;
                //int planetMass;
                
                //Console.Write("IN GRID Create\n\n\n");
                MassedComponent massedComponent = (MassedComponent)entry.Value;

                if (massedComponent is Planet)
                {
                    //cast massedC into planet
                    Planet planet = (Planet) massedComponent;
                    //plot sling forces outer ring
                    innerRadius = planet.OrbitCircle.radius;
                    outerRadius = planet.SlingCircle.radius;
                    plotOrbit(planet, innerRadius, outerRadius, galaxy, "slingForce");

                    //plot orbit force inner
                    innerRadius = planet.CrashCircle.radius;
                    outerRadius = planet.OrbitCircle.radius;
                    plotOrbit(planet, innerRadius, outerRadius, galaxy, "orbitForce");
                }
                else if (massedComponent is Sun)
                {//Sun has no orbit
                    Sun sun = (Sun) massedComponent;
                    //plot sling forces outer ring
                    innerRadius = sun.CrashCircle.radius;
                    outerRadius = sun.SlingCircle.radius;
                    plotOrbit(sun, innerRadius, outerRadius, galaxy, "slingForce");
                }
                else if (massedComponent is Blackhole)
                {
                    Blackhole blackhole = (Blackhole)massedComponent;
                    //plot sling forces outer ring
                    innerRadius = blackhole.CrashCircle.radius;
                    outerRadius = blackhole.SlingCircle.radius;
                    plotOrbit(blackhole, innerRadius, outerRadius, galaxy, "slingForce");
                }



            }

            public static void collisionShipPlanet()
            {
                //occurs if ship actually collides with planet (i think?), happens in galaxy: moveShip()
                
                //boom
                
            }

            private static void plotOrbit(MassedComponent massedComponent, double innerRadius, double outerRadius, Map galaxy, String typeOfForce)
            {
                int maxX;
                double maxY;
                int centerX;
                int centerY;
                maxY = (int)outerRadius;
                maxX = (int)outerRadius;

                GenericForce[,] newGravityMap = galaxy.galaxyForces;
                //X and Y counters we will be using to mark inside of orbit
                int xCounter = maxX;
                int yCounter = 0;



                //Find slingshot orbit center(x,y) of this massed component 
                centerX = (int)massedComponent.SlingCircle.centerPOS.X;
                centerY = (int)massedComponent.SlingCircle.centerPOS.Y;

                //Only calculate 90% and reflect it for other 3 quadrents ie 270%
                while (xCounter >= 0 && yCounter <= maxY) //start at the right when x=maxX and y = 0;
                {
                    //if the product of the x and y coordinates are less than the radius
                    if (Math.Sqrt(xCounter * xCounter + yCounter * yCounter) <= outerRadius)
                    {
                        //mark all squares from the center up to x
                        //NOTE: only Squares outside the crash radius needs to be marked, so we can detect its in either crash or sling orbits
                        /**
                                 *    ***
                                 *    ******
                                 *    ********
                                 *  ()********
                                 */
                        for (int x = 0; x <= xCounter; x++)
                        {

                                markGravityMapGrid(x, yCounter, massedComponent, galaxy, typeOfForce); //Mark up to x only

                        }
                        //move up one y do it again
                        //Console.Out.WriteLine("Incremented Y " + yCounter);
                        yCounter++;
                    }
                    else                             //move to the left 1 x try again
                    {
                        //System.Console.Out.WriteLine("MarkGrid MOVING TO NEXT LINE x_ " + xCounter);
                        xCounter--;
                    }


                }
            }

            /// <summary>
            /// Mark the global forces on the Gravity map grid, by reflecting for each quadrant
            /// </summary>
            /// <param name="xRelative"></param> x position from the origin being centre
            /// <param name="yRelative"></param> y position from the origin being centre
            /// <param name="centerX"></param> x center of the massed object
            /// <param name="centerY"></param> y center of the massed object
            private static void markGravityMapGrid(int xRelative, int yRelative,  MassedComponent massedObject, Map galaxy,  String typeOfForce)
            {

                //GenericForce gravity;

                GenericForce[,] gravityMap = galaxy.galaxyForces;
                float[,] absoluteForceMap = galaxy.absoluteForceMap;
                int xGlobal;
                int yGlobal;
                int quadrant;

                    //TODO: Check and sum forces
                    //Bottom right quadrant
                    //Find the x and y global to the grid
                    xGlobal = xRelative + (int)massedObject.SlingCircle.centerPOS.X;
                    yGlobal = yRelative + (int)massedObject.SlingCircle.centerPOS.Y;
                    quadrant = 4;


                     GenericForce newGravityForce = new GenericForce();
                    //TODO: Check if xGlobal and yGlobal are out of bounds
                    //Console.WriteLine("Quadrant " + quadrant + " x,y = [" + xGlobal + "," + yGlobal + "]");
                    if ((xGlobal >= 0 ) && (yGlobal >= 0) && (xGlobal < gravityMap.GetLength(0)) && (yGlobal < gravityMap.GetLength(1)))
                    {
                    
                        newGravityForce = calculateGravityForces(xRelative, yRelative, massedObject.Mass, quadrant, typeOfForce, massedObject);
                        //Add the old vectors to the new vectors
//                        if (newGravityForce.Force.X < 0.0000000000000001 && newGravityForce.Force.X > -0.0000000000000001 || newGravityForce.Force.Y.Equals(0))
//                            newGravityForce = gravityMap[xGlobal, yGlobal];
//                        else
                            newGravityForce.addVectors(gravityMap[xGlobal, yGlobal].Force);
                        /*
                        newGravityForce.addVectors(gravityMap[xGlobal, yGlobal].Force);
                        if (!gravityMap[xGlobal, yGlobal].Force.Equals(Vector2.Zero))
                        {
                            if (newGravityForce.Force.X.Equals(0) && gravityMap[xGlobal, yGlobal].Force.X.Equals(0) ||
                                newGravityForce.Force.Y.Equals(0) && gravityMap[xGlobal, yGlobal].Force.Y.Equals(0))
                            {
                                //revert we just added twice
                                newGravityForce = gravityMap[xGlobal, yGlobal];
                            }
                        }
                        */
                        gravityMap[xGlobal, yGlobal] = newGravityForce;
                        absoluteForceMap[xGlobal, yGlobal] =  (float)(Math.Sqrt(newGravityForce.Force.X * newGravityForce.Force.X + newGravityForce.Force.Y * newGravityForce.Force.Y));
                      //  if (absoluteForceMap[xGlobal, yGlobal] > galaxy.maxAbsForce)
                      //      galaxy.maxAbsForce = absoluteForceMap[xGlobal, yGlobal];
                    }

  
                    /*if((gravity.Force.X < 0)  || (gravity.Force.Y < 0) ){
                        Console.WriteLine("["+gravity.Force.X + "," +gravity.Force.Y+"]");
                    }*/
                 

                    //Bottom left quadrant(Bottom left in pic)
                    //Find the x and y global to the grid

                    xGlobal = -xRelative + (int)massedObject.SlingCircle.centerPOS.X;
                    yGlobal = yRelative + (int)massedObject.SlingCircle.centerPOS.Y;
                    quadrant = 3;

                    //Console.WriteLine("Quadrant " + quadrant + " x,y = [" + xGlobal + "," + yGlobal + "]");
                    if ((xGlobal >= 0) && (yGlobal >= 0) && (xGlobal < gravityMap.GetLength(0)) && (yGlobal < gravityMap.GetLength(1)))
                    {
                        newGravityForce = calculateGravityForces(xRelative, yRelative, massedObject.Mass, quadrant, typeOfForce, massedObject);
                        //Add the old vectors to the new vectors
                        if (newGravityForce.Force.X < 0.0000000000000001 && newGravityForce.Force.X > -0.0000000000000001 || newGravityForce.Force.Y.Equals(0))
                            newGravityForce = gravityMap[xGlobal, yGlobal];
                        else
                            newGravityForce.addVectors(gravityMap[xGlobal, yGlobal].Force);
                        /*
                        newGravityForce.addVectors(gravityMap[xGlobal, yGlobal].Force);
                        if (!gravityMap[xGlobal, yGlobal].Force.Equals(Vector2.Zero))
                        {
                            if (newGravityForce.Force.X.Equals(0) && gravityMap[xGlobal, yGlobal].Force.X.Equals(0) ||
                                newGravityForce.Force.Y.Equals(0) && gravityMap[xGlobal, yGlobal].Force.Y.Equals(0))
                            {
                                //revert we just added twice
                                newGravityForce = gravityMap[xGlobal, yGlobal];
                            }
                        }
                         */
                        gravityMap[xGlobal, yGlobal] = newGravityForce;
                        absoluteForceMap[xGlobal, yGlobal] = (float)Math.Sqrt(newGravityForce.Force.X * newGravityForce.Force.X + newGravityForce.Force.Y * newGravityForce.Force.Y);
                      //  if (absoluteForceMap[xGlobal, yGlobal] > galaxy.maxAbsForce)
                      //      galaxy.maxAbsForce = absoluteForceMap[xGlobal, yGlobal];
                    }

                    //top right quadrant
                    //Find the x and y global to the grid
                    xGlobal = xRelative + (int)massedObject.SlingCircle.centerPOS.X;
                    yGlobal = -yRelative + (int)massedObject.SlingCircle.centerPOS.Y;
                    quadrant = 1;

                    //Console.WriteLine("Quadrant " + quadrant + " x,y = [" + xGlobal + "," + yGlobal + "]");
                    if ((xGlobal >= 0) && (yGlobal >= 0) && (xGlobal < gravityMap.GetLength(0)) && (yGlobal < gravityMap.GetLength(1)))
                    {
                        newGravityForce = calculateGravityForces(xRelative, yRelative, massedObject.Mass, quadrant, typeOfForce, massedObject);
                        //Add the old vectors to the new vectors
                        if (newGravityForce.Force.X < 0.0000000000000001 && newGravityForce.Force.X > -0.0000000000000001 || newGravityForce.Force.Y.Equals(0))
                            newGravityForce = gravityMap[xGlobal, yGlobal];
                        else
                            newGravityForce.addVectors(gravityMap[xGlobal, yGlobal].Force);
                        /*
                        newGravityForce.addVectors(gravityMap[xGlobal, yGlobal].Force);
                        if (!gravityMap[xGlobal, yGlobal].Force.Equals(Vector2.Zero))
                        {
                            if (newGravityForce.Force.X.Equals(0) && gravityMap[xGlobal, yGlobal].Force.X.Equals(0) ||
                                newGravityForce.Force.Y.Equals(0) && gravityMap[xGlobal, yGlobal].Force.Y.Equals(0))
                            {
                                //revert we just added twice
                                newGravityForce = gravityMap[xGlobal, yGlobal];
                            }
                        }
                         */
                        gravityMap[xGlobal, yGlobal] = newGravityForce;
                        absoluteForceMap[xGlobal, yGlobal] = (float)Math.Sqrt(newGravityForce.Force.X * newGravityForce.Force.X + newGravityForce.Force.Y * newGravityForce.Force.Y);
                        //if (absoluteForceMap[xGlobal, yGlobal] > galaxy.maxAbsForce)
                         //   galaxy.maxAbsForce = absoluteForceMap[xGlobal, yGlobal];
                    }

                    //top left quadrant
                    //Find the x and y global to the grid
                    xGlobal = -xRelative + (int)massedObject.SlingCircle.centerPOS.X;
                    yGlobal = -yRelative + (int)massedObject.SlingCircle.centerPOS.Y;
                    quadrant = 2;

                    //Console.WriteLine("Quadrant " + quadrant + " x,y = [" + xGlobal + "," + yGlobal + "]");
                    if ((xGlobal >= 0) && (yGlobal >= 0) && (xGlobal < gravityMap.GetLength(0)) && (yGlobal < gravityMap.GetLength(1)))
                    {
                        newGravityForce = calculateGravityForces(xRelative, yRelative, massedObject.Mass, quadrant, typeOfForce, massedObject);
                        //Add the old vectors to the new vectors
//                        if (newGravityForce.Force.X < 0.0000000000000001 && newGravityForce.Force.X > -0.0000000000000001 || newGravityForce.Force.Y.Equals(0))
//                            newGravityForce = gravityMap[xGlobal, yGlobal];
//                        else
                            newGravityForce.addVectors(gravityMap[xGlobal, yGlobal].Force);
                        /*
                        newGravityForce.addVectors(gravityMap[xGlobal, yGlobal].Force);
                        if (!gravityMap[xGlobal, yGlobal].Force.Equals(Vector2.Zero))
                        {
                            if (newGravityForce.Force.X.Equals(0) && gravityMap[xGlobal, yGlobal].Force.X.Equals(0) ||
                                newGravityForce.Force.Y.Equals(0) && gravityMap[xGlobal, yGlobal].Force.Y.Equals(0))
                            {
                                //revert we just added twice
                                newGravityForce = gravityMap[xGlobal, yGlobal];
                            }
                        }
                         */ 
                        gravityMap[xGlobal, yGlobal] = newGravityForce;
                        absoluteForceMap[xGlobal, yGlobal] = (float)Math.Sqrt(newGravityForce.Force.X * newGravityForce.Force.X + newGravityForce.Force.Y * newGravityForce.Force.Y);
                        //if (absoluteForceMap[xGlobal, yGlobal] > galaxy.maxAbsForce)
                          //  galaxy.maxAbsForce = absoluteForceMap[xGlobal, yGlobal];
                    }
            }
                                    //Covering edge case when xRelative or yRelative is 0
                        //if we are not adding to vector with force 0, the sum of our forces should be less abs() than the indivicual parts
                        // as the overlapping of two planetary forces would negate each other
                       /* if (!gravityMap[xGlobal, yGlobal].Force.Equals(Vector2.Zero))
                        {
                            if (Math.Abs(newGravityForce.Force.X) > Math.Abs(gravityMap[xGlobal, yGlobal].Force.X) && Math.Abs(newGravityForce.Force.Y) > Math.Abs(gravityMap[xGlobal, yGlobal].Force.Y))
                            {
                                //Revert:we have are at the axis and wrongly calculated and added forces twice
                                newGravityForce = gravityMap[xGlobal, yGlobal];
                            }
                        }*/


            /// <summary>
            /// Calculates the gravity forces based on k_looks_good
            /// </summary>
            /// <param name="xCounter"></param> the counters are relative to the origin of the circle
            /// <param name="yCounter"></param>
            /// <param name="mass"></param>
            /// 
            /// <returns> A gravity x and y force vector</returns>
            private static GenericForce calculateGravityForces(int xRelative, int yRelative, double mass, int quadrant, String typeOfForce, MassedComponent massedObject)
            {
                GenericForce gravity = null;
                if (typeOfForce.Equals("slingForce"))
                {
                    SlingForce slingForce = new SlingForce();
                    //TODO: calculate acceleration based on how close to planet
                    slingForce.Acceleration = 1.1f;
                    gravity = slingForce;
                    //gravity.Acceleration = 1.1f;
                }
                else if (typeOfForce.Equals("orbitForce"))
                {
                    gravity = new OrbitForce();
                }else
                {
                    gravity = new GenericForce();
                }

                float force = (PhysicsEngine.k_looks_good*massedObject.Mass)/ (float)Math.Pow(Math.Sqrt(xRelative * xRelative + yRelative * yRelative),2);

                double theta = Math.Atan2(yRelative, xRelative);
                //test
                double  xForce = force * Math.Cos(theta);
                double  yForce = force * Math.Sin(theta);

                if (xForce < minXForce)
                    minXForce = xForce;
                //else if (yForce == 0)
                  //  Console.WriteLine("Y zero");

                //quadrant 1 -x y
                if (quadrant == 1)
                {
                    xForce = -1*xForce;
                }
                //quadrant 2 x y
                else if (quadrant == 2)
                {
                    
                }
                //quadrant 3 x -y
                else if(quadrant ==3)
                {
                    yForce = -1*yForce;
                }
                //quadrant 4 -x -y
                else if(quadrant ==4)
                {
                    xForce = -1*xForce;
                    yForce = -1*yForce;
                }  
                //Console.Out.WriteLine("["+xForce+","+yForce+"]");
                gravity.Force = new Vector2((float)xForce, (float)yForce);


                return gravity;


            }
            /* NONE OF THESE WERE USED
            float solnMass;
            float solnFuel;
            float solnHull;
            float solnSpeed;
            float solnCredits;
            int xSize;
            int ySize;
            LinkedList<Vector2>.Enumerator orbitEnum;
            private int k_looks_good;
            private Texture2D backgroundTex;
            */

            public static void generateColorMap(GraphicsDevice graphics, Map galaxyMap)
            {
                float total = 0;
                float nForceSqrs = 0;
                int index = 0;
                int red = 0;
                int blue = 0;
                int xSize = galaxyMap.getXSize();
                int ySize = galaxyMap.getYSize();

                Texture2D coloredMap = new Texture2D(graphics, xSize, ySize);
                Color[] pixelColorArray = new Color[(coloredMap.Width* coloredMap.Height)];


                float[,] absValMap = galaxyMap.absoluteForceMap;    //get the 2d array of absolute force value, created in physicsengine

                //set gradient. 255,0 = maxForce; 0,255 = no Force

                int[,] colorMap = new int[xSize, ySize];    //colorMap will be a 2-d array that holds the color value x (int between 0 and 255) red value = x, green value = 0, blue value = 255 - x.
                


                /**
                 * Calculate the average of all the squares with forces multiply by 2 and set it as the maxForce
                 */

                for (int i = 0; i < xSize; i++)
                {

                    for (int j = 0; j < ySize; j++)
                    {
                        if (absValMap[i,j] > 0)
                        {
                            total += absValMap[i, j];
                            nForceSqrs++;
                        }
             
                    }
                 
                }
                //2*avg = max
                galaxyMap.maxAbsForce = (total/nForceSqrs)*(7/3);
                float maxForce = galaxyMap.maxAbsForce;             //get the highest absolute force from physicsengine

                index = pixelColorArray.Length;
                /*
                 * Find x to calculate color for each pixel
                 * Create an array of color objects based on the x values for each pixel
                 * to set the color of the overlay texture
                 */
                int color_looksGood = 5;

                for (int j = ySize-1; j > 0; j--)
                {
                    for (int i = xSize - 1; i > 0; i--)
                    {

                  
                        colorMap[i, j] = (int)Round(((absValMap[i, j] *color_looksGood)/ maxForce) * 255);
                        
                        if (index < pixelColorArray.Length)
                        {
                            red = colorMap[i, j];
            
                            blue = (255 - colorMap[i, j]);

                            pixelColorArray[index] = new Color(red, 0, blue,
                                                               colorMapTransparency);
                        }
                        index--;
                    }
                    index--;
                }


                //Store the color array in map
                galaxyMap.colorMap = colorMap;

                galaxyMap.visualForcesTex = coloredMap;
                coloredMap.SetData(pixelColorArray);



            }
            public static double Round(double value)
            {
                double difference = Math.Abs((value - Math.Floor(value)));
                //Round off or up
                if (difference >= 0.5d)
                {
                    return Math.Ceiling(value);

                }else
                {
                    return Math.Floor(value);
                }
            }

            public static String ToStringGalaxy(Map galaxy, Boolean verbose)
            {
                String rtString = "";
                GenericForce squareForce;

                int xSize = galaxy.getXSize();
                int ySize = galaxy.getYSize();
                int x = 0;

                for (int y = 0; y < 200; y++)//xSize
                {

                    for (x = 0; x <200 ; x++)//ySize
                    {


                        squareForce = galaxy.galaxyForces[x, y];

                        if (verbose == true && (squareForce.Force.X != 0 || squareForce.Force.Y != 0))
                        {
                            rtString += "[(" + x + "," + y + ")" + "F: (" + squareForce.Force.X + "," + squareForce.Force.Y + ")]" +
                                        " ";

                        }
                        else if (verbose == false && (squareForce.Force.X != 0 || squareForce.Force.Y != 0))
                        {
                            if ((squareForce.Force.X < 0 || squareForce.Force.Y < 0))
                            {
                                rtString += "-";
                            }
                            else
                            {

                                rtString += "*";
                            }
                        }
                        else
                        {
                            rtString += "0";

                        }
                    }
                    rtString += "\n";
                }

                return rtString;
            }
 
            private static Hashtable createGalaxyComponents()
            {
                throw new NotImplementedException();
            }
            static void main(string[] args)
            {
                
                
            }

            public static LinkedList<Vector2> generateShipOrbitPath(double orbitRadius, Vector2 planetPosition)
            {
                LinkedList<Vector2> orbitPath = new LinkedList<Vector2>();  //make a linked list for the orbit
                double adjustmentRadian = (2*Math.PI)/(4*orbitRadius);      //adjustmentRadian is full circle (2piR)/(number of points to calculate)
                //double adjustmentRadian = (Math.PI / 180);
                double yCounter = orbitRadius;                                 //start at the top of the circle

                //TODO: Need to fix. calculated positions have a distance to center that is greater than radius
                
                Vector2 nextPoint = new Vector2();                          //make a vector to store the value for the next point
                LinkedListNode<Vector2> pointToAdd;
                LinkedListNode<Vector2> previousPoint = new LinkedListNode<Vector2>(Vector2.Zero);
                Boolean down = true;

                for (double currentRadian = 0; currentRadian < 2*Math.PI; currentRadian = currentRadian + adjustmentRadian)
                {
                    nextPoint.X = (float) (int) (planetPosition.X + orbitRadius * Math.Sin(currentRadian));   //use trig to calculate next x point, casted to int to remove decimal created by sin fn
                    nextPoint.Y = (float) (int) (planetPosition.Y + orbitRadius * Math.Cos(currentRadian));   //next y point is counter


                    /*Console.WriteLine("Radians = " + currentRadian);
                    if (Vector2.Distance(nextPoint, planetPosition) > orbitRadius) //TODO: REMOVE COMMENT AFTER FIX
                    {
                        Console.WriteLine("Error. Distance larger than orbit ring. Distance = " 
                            + Vector2.Distance(nextPoint, planetPosition));
                    }*/

                    pointToAdd = new LinkedListNode<Vector2>(nextPoint);

                    if (currentRadian == 0)
                    {
                        orbitPath.AddFirst(pointToAdd);
                    }
                    else
                    {
                        orbitPath.AddAfter(previousPoint, pointToAdd);
                    }

                    previousPoint = pointToAdd;
                    orbitPath.AddLast(nextPoint);       //add new point to list
                }

                
                return orbitPath;
            }


            public static void handleCollision()
            {
                
            }

            public static int findQuadrant(Vector2 movingPosition, Vector2 staticPosition)
            {
                double xTester = (int)movingPosition.X - staticPosition.X;
                double yTester = (int)movingPosition.Y - staticPosition.Y;

                if (xTester > 0 && yTester <= 0)
                    return 1;
                else if (xTester <= 0 && yTester < 0)
                    return 2;
                else if (xTester < 0 && yTester >= 0)
                    return 3;
                else if (xTester >= 0 && yTester > 0)
                    return 4;
                else
                    return 0;
            }

            public static double calculateRadianAngle(double theta, int quadrant)
            {
                double radianAngle = -1;

                if (quadrant == 1)
                    radianAngle = theta;
                else if (quadrant == 2)
                    radianAngle = Math.PI - theta;
                else if (quadrant == 3)
                    radianAngle = theta + Math.PI;
                else if (quadrant == 4)
                    radianAngle = (2 * Math.PI) - theta;

                return radianAngle;
            }

            public static Texture2D createCircle(GraphicsDevice graphics, int radius)
            {
                int outerRadius = radius * 2 + 2; // So circle doesn't go out of bounds
                Texture2D texture = new Texture2D(graphics, outerRadius, outerRadius);

                Color[] data = new Color[outerRadius * outerRadius];

                // Colour the entire texture transparent first.
                for (int i = 0; i < data.Length; i++)
                    data[i] = Color.Transparent;

                // Work out the minimum step necessary using trigonometry + sine approximation.
                double angleStep = 1f / radius;

                for (double angle = 0; angle < Math.PI * 2; angle += angleStep)
                {
                    // Use the parametric definition of a circle: 
                    int x = (int)Math.Round(radius + radius * Math.Cos(angle));
                    int y = (int)Math.Round(radius + radius * Math.Sin(angle));

                    data[y * outerRadius + x + 1] = Color.White;
                }

                texture.SetData(data);
                return texture;
            }
    }

}